package ua.khpi.si.kit49.diploma.util;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import ua.khpi.si.kit49.diploma.core.Forecast;
import ua.khpi.si.kit49.diploma.core.Weather;

/**
 * SAXParser to parse weather service reply
 * 
 * @author netstalk3r
 * 
 */

public class SAXUtilit extends DefaultHandler {

	private InputStream inputStream;
	private Weather weather;

	Boolean flag = true;

	SAXUtilit() {
		super();
	}

	SAXUtilit(InputStream inputStream, Weather weather) {
		super();
		this.inputStream = inputStream;
		this.weather = weather;
	}

	public InputStream getIs() {
		return inputStream;
	}

	public void setIs(InputStream inputStream) {
		this.inputStream = inputStream;
	}

	public void parse() throws ParserConfigurationException, SAXException,
			IOException {

		SAXParserFactory factory = SAXParserFactory.newInstance();
		factory.setValidating(false);

		SAXParser parser = factory.newSAXParser();
		parser.parse(inputStream, this);
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {

		if (qName.equals("yweather:condition")) {
			weather.setDescription(attributes.getValue("text"));
			weather.setTemperature(Integer.parseInt(attributes.getValue("temp")));
		}

		if (qName.equals("yweather:wind")) {
			weather.setWindSpeed(Double.parseDouble(attributes
					.getValue("speed")));
			weather.setWindDirection(windDirection(attributes
					.getValue("direction")));
		}

		if (qName.equals("yweather:forecast")) {
			Forecast forecast = new Forecast();
			forecast.setDate(attributes.getValue("date"));
			if (flag) {
				weather.setDate(attributes.getValue("date"));
				flag = false;
			}
			forecast.setLow(Integer.parseInt(attributes.getValue("low")));
			forecast.setHigh(Integer.parseInt(attributes.getValue("high")));
			forecast.setDescription(attributes.getValue("text"));
			forecast.setDay(attributes.getValue("day"));
			weather.addForecast(forecast);
		}
	}

	private String windDirection(String degree) {

		Integer direction = null;

		try {
			direction = Integer.parseInt(degree);
		} catch (NumberFormatException e) {
			return "unaviable";
		}

		if (direction < 0 || direction > 360) {
			return "fail";
		}

		if (direction <= 30 || direction >= 330) {
			return "N";
		}

		if (direction < 60 || direction > 30) {
			return "NE";
		}

		if (direction <= 120 || direction >= 60) {
			return "E";
		}

		if (direction < 150 || direction > 120) {
			return "SE";
		}

		if (direction <= 210 || direction >= 150) {
			return "S";
		}

		if (direction < 240 || direction > 210) {
			return "SW";
		}

		if (direction <= 300 || direction >= 240) {
			return "W";
		}

		if (direction < 330 || direction > 300) {
			return "NW";
		}

		return "fail";
	}
}
